package com.study.concurrentprogramming.guarded;

import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * @Description : 练习保护性暂停的使用
 * @Author : guxuemin
 * @Version : V1.0.0
 * @Date : 2021/8/11 21:10
 */
@Slf4j(topic = "juc")
public class GuardedSuspend {
    public static void main(String[] args) throws InterruptedException {
        GuardedObject guardedObject = new GuardedObject();

        new Thread(() -> {
            Object consumer = guardedObject.consumer();
           log.info("result: {}", consumer);
        }, "t1").start();

        Thread thread = new Thread(() -> {
            guardedObject.produce("give you a bread");
        }, "t2");
        thread.start();
        synchronized (thread) {
            thread.wait(2000);
        }

        log.info("main exe");
    }
}
@Slf4j(topic = "juc")
class GuardedObject  {
    private Object result;

    public Object consumer() {
        synchronized (this) {
            // 避免虚假唤醒
            while (Objects.isNull(result)) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public void produce(Object obj) {
        synchronized (this) {
            log.info("produce a result");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.result = obj;
            this.notifyAll();
        }
    }
}